﻿using System;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Web;
using Super.Common;
using System.Web.Mvc;
using Microsoft.Web.Infrastructure.DynamicValidationHelper;

namespace Super.DomainService
{
    /// <summary> 数据读取类
    /// </summary>
    public class Query
    {
        private static string Decode(string s)
        {
            return HttpContext.Current.Server.UrlDecode(s);
        }

        /// <summary> 获取Url ? 后面的值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="defaultValue">获取失败时,返回的默认值</param>
        /// <param name="isEnableValidate">是否开启不安全内容验证</param>
        /// <returns></returns>
        public static string Get(string key, string defaultValue = "", bool isEnableValidate = true)
        {
            var s = HttpContext.Current.Request.Url.Query;

            if (s.Length <= 1)
                return defaultValue;
            s = s.Substring(1);

            var kv = s.Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries)
                .Select(j => j.Split('='))
                .Where(j => j.Length == 2)
                .Select(j => new { Key = j[0], Value = j[1] })
                .FirstOrDefault(j => key.Equals(j.Key, StringComparison.OrdinalIgnoreCase));

            return kv == null
                       ? defaultValue
                       : (isEnableValidate ? Decode(kv.Value).RemoveHtmlTaget() : Decode(kv.Value));


            if (isEnableValidate)
            {
                return HttpContext.Current.Request.QueryString[key] ?? defaultValue;
            }
            else
            {
                Func<NameValueCollection> formGetter;
                Func<NameValueCollection> queryStringGetter;
                ValidationUtility.GetUnvalidatedCollections(HttpContext.Current, out formGetter, out queryStringGetter);
                return queryStringGetter()[key] ?? defaultValue;
            }
        }

        /// <summary> 获取 From表单的值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="defaultValue">获取失败时,返回的默认值</param>
        /// <param name="isEnableValidate">是否开启不安全内容验证</param>
        /// <returns></returns>  
        public static string Post(string key, string defaultValue = "", bool isEnableValidate = true)
        {
            //如果有提交文件了,则不处理表单安全,,如果有不安全Html,就直接报错了.....反正有文件提交的页面也不多.
            if (HttpContext.Current.Request.Files.Count > 0)
            {
                return HttpContext.Current.Request.Form[key] ?? defaultValue;
            }

            var ism = HttpContext.Current.Request.InputStream;
            var bs = new byte[ism.Length];
            ism.Seek(0, global::System.IO.SeekOrigin.Begin);
            ism.Read(bs, 0, bs.Length);
            string s = Encoding.UTF8.GetString(bs);

            var kv = s.Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries)
                .Select(j => j.Split('='))
                .Where(j => j.Length == 2)
                .Select(j => new { Key = j[0], Value = j[1] })
                .FirstOrDefault(j => key.Equals(j.Key, StringComparison.OrdinalIgnoreCase));

            return kv == null
                       ? defaultValue
                       : (isEnableValidate ? Decode(kv.Value).RemoveHtmlTaget() : Decode(kv.Value));


            //这些代码是从MVC源码中读的做法.........但是每次都建立委托,有点不爽.
            if (isEnableValidate)
            {
                return HttpContext.Current.Request.Form[key] ?? defaultValue;
            }
            else
            {
                Func<NameValueCollection> formGetter;
                Func<NameValueCollection> queryStringGetter;
                ValidationUtility.GetUnvalidatedCollections(HttpContext.Current, out formGetter, out queryStringGetter);
                return formGetter()[key] ?? defaultValue;
            }
        }

        /// <summary>
        /// 获取GET,PARAMS,POST值 自动按顺序匹配到第一个后即返回
        /// </summary>
        /// <param name="key"></param>
        /// <param name="defaultValue">获取失败时,返回的默认值</param>
        /// <param name="isEnableValidate">是否开启不安全内容验证</param>
        /// <returns></returns>
        public static string Value(string key, string defaultValue = "", bool isEnableValidate = true)
        {
            return (Get(key, null, isEnableValidate) ?? Params(key, null)) ?? Post(key, null, isEnableValidate) ?? defaultValue;
        }

        /// <summary> 获取Url中编码参数的值.
        /// </summary>
        /// <param name="key"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public static string Params(string key, string defaultValue = "")
        {
            return URL.Query(key) ?? defaultValue;
        }

        /// <summary>
        /// 获取所有参数
        /// </summary>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public static string ToString(string defaultValue = "")
        {
            return HttpContext.Current.Request.QueryString.ToString() ?? defaultValue;
        }

        /// <summary>
        /// 获取客户端安全真实的IP
        /// </summary>
        /// <returns></returns>
        public static string IP
        {
            get
            {
                string ip;
                if (HttpContext.Current.Request.ServerVariables["HTTP_VIA"] != null && !string.IsNullOrEmpty(HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"])) //使用了代理并且有透传IP
                    ip = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
                else
                    ip = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];

                return ip.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries).Any(j => { int k; return !int.TryParse(j, out k); }) ? HttpContext.Current.Request.UserHostAddress:  ip;
            }
        }



        /// <summary> 获取传值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public string this[string key, string defaultValue = ""]
        {
            get
            {
                var rt = (Get(key) ?? Params(key)) ?? Post(key);

                return rt ?? null;
            }
        }
    }

    public static class FormCollectionEXT
    {
        /// <summary>
        /// 对FormCollection 表单的
        /// </summary>
        /// <param name="form"></param>
        /// <param name="key"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public static string Value(this FormCollection form, string key, string defaultValue = "")
        {
            return form[key] ?? defaultValue;
        }
    }
}
